<template>
  <div class="number-line-visualization">
    <div class="visualization-header">
      <h3>数轴与数字 - 交互式学习</h3>
      <p>通过拖拽数字到数轴上，理解正负数和位置关系</p>
    </div>

    <div class="visualization-container">
      <!-- 控制面板 -->
      <div class="control-panel">
        <div class="controls">
          <label>数轴范围:</label>
          <select v-model="rangeType" @change="updateRange">
            <option value="simple">简单 (-5 到 5)</option>
            <option value="medium">中等 (-10 到 10)</option>
            <option value="advanced">高级 (-20 到 20)</option>
          </select>
        </div>

        <div class="controls">
          <button @click="resetDemo" class="reset-btn">重置</button>
          <button @click="showAnswer" class="hint-btn">显示答案</button>
        </div>

        <div class="score-display">
          <span>正确: {{ correctCount }}</span>
          <span>错误: {{ incorrectCount }}</span>
        </div>
      </div>

      <!-- 可拖拽的数字 -->
      <div class="draggable-numbers">
        <h4>拖拽这些数字到数轴上的正确位置：</h4>
        <div class="numbers-container">
          <div
            v-for="number in availableNumbers"
            :key="`number-${number}`"
            class="draggable-number"
            :class="{ placed: placedNumbers.includes(number) }"
            :draggable="!placedNumbers.includes(number)"
            @dragstart="startDrag($event, number)"
          >
            {{ number }}
          </div>
        </div>
      </div>

      <!-- 数轴 -->
      <div class="number-line-container">
        <svg ref="numberLineSvg" class="number-line-svg" :viewBox="`0 0 ${svgWidth} ${svgHeight}`">
          <!-- 主轴线 -->
          <line
            :x1="padding"
            :y1="svgHeight / 2"
            :x2="svgWidth - padding"
            :y2="svgHeight / 2"
            stroke="#333"
            stroke-width="3"
          />

          <!-- 刻度线和标签 -->
          <g v-for="i in tickMarks" :key="`tick-${i}`">
            <!-- 刻度线 -->
            <line
              :x1="getTickX(i)"
              :y1="svgHeight / 2 - tickHeight"
              :x2="getTickX(i)"
              :y2="svgHeight / 2 + tickHeight"
              stroke="#333"
              stroke-width="2"
            />

            <!-- 数字标签 -->
            <text
              :x="getTickX(i)"
              :y="svgHeight / 2 + 35"
              text-anchor="middle"
              font-size="14"
              fill="#333"
            >
              {{ i }}
            </text>
          </g>

          <!-- 零点标记 -->
          <circle :cx="getTickX(0)" :cy="svgHeight / 2" r="5" fill="#e74c3c" />

          <!-- 放置区域 -->
          <g v-for="i in tickMarks" :key="`drop-zone-${i}`">
            <circle
              :cx="getTickX(i)"
              :cy="svgHeight / 2 - 60"
              r="25"
              fill="transparent"
              stroke="#ddd"
              stroke-width="2"
              stroke-dasharray="5,5"
              class="drop-zone"
              @dragover.prevent
              @drop="handleDrop($event, i)"
            />
          </g>

          <!-- 已放置的数字 -->
          <g v-for="(number, position) in numberPositions" :key="`placed-${position}`">
            <circle
              :cx="getTickX(Number(position))"
              :cy="svgHeight / 2 - 60"
              r="20"
              :fill="isCorrectPosition(number, Number(position)) ? '#2ecc71' : '#e74c3c'"
            />
            <text
              :x="getTickX(Number(position))"
              :y="svgHeight / 2 - 55"
              text-anchor="middle"
              font-size="16"
              fill="white"
              font-weight="bold"
            >
              {{ number }}
            </text>
          </g>
        </svg>
      </div>

      <!-- 学习提示 -->
      <div class="learning-tips">
        <div class="tip-section">
          <h4>💡 学习要点：</h4>
          <ul>
            <li><strong>正数</strong>：在数轴上位于0的右侧，数值越大，位置越靠右</li>
            <li><strong>负数</strong>：在数轴上位于0的左侧，数值越小，位置越靠左</li>
            <li><strong>零</strong>：数轴的原点，既不是正数也不是负数</li>
            <li><strong>比较</strong>：数轴上右边的数比左边的数大</li>
          </ul>
        </div>

        <div v-if="feedback" class="feedback" :class="feedback.type">
          {{ feedback.message }}
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
defineOptions({ name: 'NumberLineVisualization' })

// 响应式数据
const rangeType = ref('simple')
const placedNumbers = ref<number[]>([])
const numberPositions = ref<Record<number, number>>({}) // position -> number
const correctCount = ref(0)
const incorrectCount = ref(0)
const feedback = ref<{ type: 'success' | 'error'; message: string } | null>(null)

// SVG 尺寸配置
const baseWidth = 800
const svgHeight = 200
const basePadding = 60
const tickHeight = 15

// 根据范围动态计算SVG宽度和间距
const svgWidth = computed(() => {
  // 范围越大，宽度越大，确保刻度线不重叠
  // 简单：800px, 中等：1000px, 高级：1400px
  if (rangeType.value === 'simple') return 800
  if (rangeType.value === 'medium') return 1000
  if (rangeType.value === 'advanced') return 1400
  return baseWidth
})

const padding = computed(() => {
  // 范围越大，左右边距越大
  // 简单：60px, 中等：80px, 高级：100px
  if (rangeType.value === 'simple') return 60
  if (rangeType.value === 'medium') return 80
  if (rangeType.value === 'advanced') return 100
  return basePadding
})

// 数轴范围配置
const ranges: Record<string, { min: number; max: number }> = {
  simple: { min: -5, max: 5 },
  medium: { min: -10, max: 10 },
  advanced: { min: -20, max: 20 },
}

// 计算属性
const currentRange = computed(() => ranges[rangeType.value])

const tickMarks = computed(() => {
  const marks: number[] = []
  for (let i = currentRange.value.min; i <= currentRange.value.max; i++) {
    marks.push(i)
  }
  return marks
})

const availableNumbers = computed(() => {
  const { min, max } = currentRange.value
  const numbers: number[] = []

  // 生成一些随机数字，包含正数、负数和零
  const count = rangeType.value === 'simple' ? 6 : rangeType.value === 'medium' ? 8 : 10
  const possibleNumbers: number[] = []

  for (let i = min; i <= max; i++) {
    possibleNumbers.push(i)
  }

  // 随机选择数字
  for (let i = 0; i < count; i++) {
    const randomIndex = Math.floor(Math.random() * possibleNumbers.length)
    const number = possibleNumbers[randomIndex]
    numbers.push(number)
    possibleNumbers.splice(randomIndex, 1)
  }

  return numbers.sort(() => Math.random() - 0.5) // 随机打乱
})

// 方法
const getTickX = (value: number) => {
  const { min, max } = currentRange.value
  const range = max - min
  const ratio = (value - min) / range
  return padding.value + ratio * (svgWidth.value - 2 * padding.value)
}

const isCorrectPosition = (number: number, position: number) => {
  const result = number === position
  // console.log(`检查位置: 数字=${number}, 位置=${position}, 正确=${result}`)
  return result
}

const startDrag = (event: DragEvent, number: number) => {
  if (event.dataTransfer) {
    event.dataTransfer.setData('text/plain', number.toString())
  }
}

const handleDrop = (event: DragEvent, position: number) => {
  event.preventDefault()
  if (event.dataTransfer) {
    const number = parseInt(event.dataTransfer.getData('text/plain'))

    // 检查该位置是否已有数字
    if (numberPositions.value[position]) {
      showFeedback('error', '该位置已有数字！')
      return
    }

    // 放置数字
    numberPositions.value[position] = number
    placedNumbers.value.push(number)

    // 检查是否正确
    // console.log(`拖拽完成: 数字=${number}, 位置=${position}`)
    if (isCorrectPosition(number, position)) {
      correctCount.value++
      showFeedback('success', `正确！${number} 放在了正确的位置`)
    } else {
      incorrectCount.value++
      showFeedback('error', `错误！${number} 应该放在 ${number} 的位置`)
    }

    // 检查是否完成
    if (placedNumbers.value.length === availableNumbers.value.length) {
      const allCorrect = Object.entries(numberPositions.value).every(
        ([pos, num]) => parseInt(pos) === num,
      )
      if (allCorrect) {
        setTimeout(() => {
          showFeedback('success', '🎉 恭喜！你已经掌握了数轴上数字的位置关系！')
        }, 500)
      }
    }
  }
}

const showFeedback = (type: 'success' | 'error', message: string) => {
  feedback.value = { type, message }
  setTimeout(() => {
    feedback.value = null
  }, 3000)
}

const resetDemo = () => {
  placedNumbers.value = []
  numberPositions.value = {}
  correctCount.value = 0
  incorrectCount.value = 0
  feedback.value = null
}

const updateRange = () => {
  resetDemo()
}

const showAnswer = () => {
  // 显示所有数字的正确位置提示
  const hints = availableNumbers.value.map((num) => `${num} → 位置 ${num}`).join(', ')
  showFeedback('success', `提示：${hints}`)
}

onMounted(() => {
  resetDemo()
})
</script>

<style lang="less" scoped>
@import '@/styles/variables.less';
@import '@/styles/NumberLineVisualization.less';
</style>
